{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "992c2188-dfcb-4eb5-b8f2-92c12534b540",
   "metadata": {},
   "source": [
    "### Python 中的对象与引用机制\n",
    "在 Python 里，“引用” 指的是变量和对象之间的关联关系。变量本身并不直接存储对象的数据，而是存储了对象在内存中的地址，借助这个地址就能找到对应的对象。\n",
    "变量其实是对象的引用。当你创建一个对象时，Python 会在内存中为该对象分配一块空间，变量则存储了这个对象在内存中的地址。例如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "fdf42548-3e7c-44d2-b020-7b789c01e624",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1, 2, 3]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5bb7bba-a556-4540-be4c-a96ac08ff3af",
   "metadata": {},
   "source": [
    "这里，[1, 2, 3] 是一个列表对象，Python 为其在内存中分配了一块空间，变量 a 存储的是这个列表对象在内存中的地址，也就是 a 引用了这个列表对象。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "650d83dd-f5f8-46b9-b12b-1d9f26698c0a",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Variable:\n",
    "    def __init__(self, data):\n",
    "        self.data = data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8bc06f2-3ce3-4cd3-82da-7b0f82075ee8",
   "metadata": {},
   "source": [
    "当执行 self.data = data 时，传入的 data 已经是一个对象，它在内存中已经有了对应的地址。这行代码的作用是让实例的 data 属性（也就是 self.data）存储与 data 相同的内存地址，即让 self.data 也引用同一个对象。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "70f0c784-4455-41e7-b011-20c5a0fb4da8",
   "metadata": {},
   "source": [
    "由于 self.data 和传入的 data 引用的是同一个对象，所以如果对这个对象进行修改，无论是通过 self.data 还是传入的 data 变量，都会影响到同一个对象。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "97935e23-02e4-44d2-88a6-f014a3b104a9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "original_data 的内存地址: 1830088712768\n",
      "var.data 的内存地址: 1830088712768\n"
     ]
    }
   ],
   "source": [
    "class Variable:\n",
    "    def __init__(self, data):\n",
    "        self.data = data\n",
    "\n",
    "# 创建一个列表对象\n",
    "original_data = [1, 2, 3]\n",
    "print(f\"original_data 的内存地址: {id(original_data)}\")\n",
    "\n",
    "# 创建 Variable 类的实例\n",
    "var = Variable(original_data)\n",
    "print(f\"var.data 的内存地址: {id(var.data)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b58399cb-c877-49c2-afb6-b994a1fd1d4b",
   "metadata": {},
   "source": [
    "## self的作用\n",
    "在 Python 里，self 一般作为类方法的首个参数，其作用主要是引用类的实例对象。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eb02adfc-dfa1-4de7-82b1-88bc73a1a14c",
   "metadata": {},
   "source": [
    "self 代表类的实例对象，在调用类的方法时，Python 会自动把实例对象作为第一个参数传递给 self。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "c1b51803-c9c2-4584-9ab3-c9c8074ad7de",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<__main__.MyClass object at 0x000001AA1B1E7C50>\n"
     ]
    }
   ],
   "source": [
    "class MyClass:\n",
    "    def my_method(self):\n",
    "        print(self)\n",
    "\n",
    "obj = MyClass()\n",
    "obj.my_method()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a575db4-4aa7-4a94-b5e4-3ca4cdb65090",
   "metadata": {},
   "source": [
    "在这个例子中，obj.my_method() 调用时，Python 会自动把 obj 作为第一个参数传递给 self，所以 self 就代表了 obj 这个实例对象。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:base] *",
   "language": "python",
   "name": "conda-base-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
